import React, { useState, useMemo } from 'react'
import { Image, Text, View, switchTab, navigateTo } from 'remax/one'
import { Navigator, showToast, requestPayment } from 'remax/wechat'
import RecycleView from 'remax-recycle-view/lib'
import { Checkbox, Button, Radio, Row, Space, Tag } from 'annar'
import dayjs from 'dayjs'
import isoWeek from 'dayjs/plugin/isoWeek'
import useCloud, { requestCloud, mutateCloud } from '@/hooks/use-cloud'
import useLocation from '@/hooks/use-location'
import Login from '@/components/login'
import styles from './index.css'
dayjs.extend(isoWeek)

interface Checkable {
  checked?: boolean
  check?: (c: boolean, v: string) => void
}

const PromotionItem = ({
  _id,
  name,
  description,
  imgUrls,
  price,
  originalPrice,
  checked = false,
  check,
}: WBG.Promotion & Checkable) => {
  return (
    <View className={styles.itemArea}>
      <View
        className={styles.itemBox}
        hoverClassName="hover"
        onTap={() => {
          if (check) {
            check(!checked, _id)
          } else {
            navigateTo({ url: `/pages/promotion/index?_id=${_id}` })
          }
        }}
      >
        <Row className={styles.fullHeight} align="middle">
          {check ? (
            <Radio checked={checked} style={{ margin: '0 0 0 20px' }} />
          ) : (
            <View />
          )}
          <View className={styles.itemBoxLeft}>
            <Image
              className={styles.avatarImg}
              src={imgUrls[0]}
              mode="aspectFill"
            />
          </View>
          <Space className={styles.itemBoxRight} direction="vertical" size={12}>
            <View className="large-text ellipsis">{name}</View>
            <View className="small-text ellipsis">{description}</View>
            <Space align="center" size={12}>
              <Text className={styles.alarmText}>￥{price}</Text>
              <Text className={styles.deletedText}>￥{originalPrice}</Text>
            </Space>
          </Space>
        </Row>
      </View>
    </View>
  )
}

const ScreenItem = ({
  _id,
  name,
  imgUrls,
  coverage,
  price,
  checked,
  check,
}: WBG.Screen & Checkable) => {
  return (
    <View className={styles.itemArea}>
      <View
        className={styles.itemBox}
        hoverClassName="hover"
        onTap={() => {
          if (check) {
            check(!checked, _id)
          } else {
            navigateTo({ url: `/pages/screen/index?_id=${_id}` })
          }
        }}
      >
        <Row className={styles.fullHeight} align="middle">
          {check ? (
            <Checkbox checked={checked} style={{ margin: '0 0 0 20px' }} />
          ) : (
            <View />
          )}
          <View className={styles.itemBoxLeft}>
            <Image
              className={styles.avatarImg}
              src={imgUrls[0]}
              mode="aspectFill"
            />
          </View>
          <Space className={styles.itemBoxRight} direction="vertical" size={12}>
            <View className="large-text ellipsis">{name}</View>
            <Row className={styles.centerText} justify="space-around">
              <View>
                <View>
                  <Text className="large-text">{coverage}</Text>
                  <Text className="small-text">人</Text>
                </View>
                <Text className="small-text">覆盖人数(约)</Text>
              </View>
              <View>
                <View>
                  <Text className="small-text">￥</Text>
                  <Text className="large-text">
                    {Math.round((price / 7) * 10) / 10}
                  </Text>
                </View>
                <Text className="small-text">每日广告价格</Text>
              </View>
            </Row>
          </Space>
        </Row>
      </View>
    </View>
  )
}

export default () => {
  const { data: pData, mutate: pMutate } = useCloud('list-promotion')
  const [pLoading, setPLoading] = useState(false)
  const [promotionId, setPromotionId] = useState<string>()

  const { location } = useLocation()
  const { data: sData, mutate: sMutate } = useCloud(
    location ? 'list-screen' : null,
    {
      location,
    }
  )
  const sMap = useMemo(
    () =>
      new Map<string, WBG.Screen>(sData?.map((v: WBG.Screen) => [v._id, v])),
    [sData]
  )
  const [sLoading, setSLoading] = useState(false)
  const [screenIds, setScreenIds] = useState<string[]>([])

  const [weeks, setWeeks] = useState<string[]>(
    (() => {
      const defaultWeeks = []
      const now = dayjs()
      for (let i = 1; i <= 4; i++) {
        const week = now
          .add(7 * i, 'day')
          .startOf('isoWeek')
          .format('YYYY-MM-DD')
        defaultWeeks.push(week)
      }
      return defaultWeeks
    })()
  )

  const [step, setStep] = useState(0)
  const [agreement, setAgreement] = useState(false)

  const pAuditedData = pData?.filter(
    (v: WBG.Promotion) => v.audit?.status === 1
  )

  const casts = useMemo(
    () =>
      screenIds
        .map(v => {
          const screen = sMap.get(v) as WBG.Screen
          return {
            screenId: v,
            screenPrice: screen.price,
            weeks: weeks.filter(w => {
              const cast = screen.casts?.find((c: any) => c.week === w)
              return !cast || cast.promotions.length < 6
            }),
          }
        })
        .filter(v => v.weeks?.length),
    [sData, screenIds, weeks]
  )
  const weekCount = casts.reduce((pre, cur) => pre + cur.weeks.length, 0)

  const originalCost = casts.reduce(
    (pre, cur) => pre + cur.weeks.length * cur.screenPrice,
    0
  )
  let cost
  if (originalCost < 800) {
    cost = originalCost
  } else if (originalCost < 1200) {
    cost = originalCost * 0.875
  } else if (originalCost < 1600) {
    cost = originalCost * 0.8
  } else {
    cost = originalCost * 0.75
  }

  const weekOptions = useMemo(() => {
    const now = dayjs()
    const weekOptions: {
      week: string
      soldoutCount: number
      almostSoldoutCount: number
    }[] = []
    for (let i = 1; i <= 12; i++) {
      const week = now
        .add(7 * i, 'day')
        .startOf('isoWeek')
        .format('YYYY-MM-DD')
      const [soldoutCount, almostSoldoutCount] = screenIds.reduce(
        (pre, cur) => {
          const screen = sMap.get(cur) as WBG.Screen
          const cast = screen.casts?.find(v => v.week === week)
          if (cast && cast.promotions.length === 6) {
            return [pre[0] + 1, pre[1]]
          } else if (cast && cast.promotions.length >= 4) {
            return [pre[0], pre[1] + 1]
          } else {
            return pre
          }
        },
        [0, 0]
      )
      weekOptions.push({
        week,
        soldoutCount,
        almostSoldoutCount,
      })
    }
    return weekOptions
  }, [sData, screenIds])

  const totalWeekCount = screenIds.length * weekOptions.length
  const [soldoutWeekCount, almostSoldoutWeekCount] = weekOptions.reduce(
    (pre, cur) => {
      return [pre[0] + cur.soldoutCount, pre[1] + cur.almostSoldoutCount]
    },
    [0, 0]
  )

  return (
    <Login>
      <View className={styles.bottomArea}>
        <Row justify="space-between" align="middle">
          <Button
            type="primary"
            style={step === 0 ? { visibility: 'hidden' } : undefined}
            disabled={step === 0 ? true : false}
            onTap={() => {
              setStep(step - 1)
            }}
          >
            上一步
          </Button>
          <Text className={styles.selectTipText}>
            {step === 0
              ? `${promotionId ? '已' : '请'}选择广告`
              : step === 1
              ? screenIds.length
                ? `已选择 ${screenIds.length} 个大屏`
                : '请选择大屏'
              : step === 2
              ? weeks.length
                ? `已选择 ${weekCount} 个广告位`
                : '请选择广告排期'
              : '投放确认'}
          </Text>
          <Button
            type="primary"
            disabled={
              !(
                (step === 0 && promotionId) ||
                (step === 1 && screenIds.length) ||
                (step === 2 && weekCount) ||
                (step === 3 && agreement)
              )
            }
            onTap={async () => {
              if (step < 3) {
                setStep(step + 1)
              } else {
                try {
                  const { payment } = await requestCloud('add-order', {
                    promotionId,
                    casts: casts.map(v => ({
                      screenId: v.screenId,
                      weeks: v.weeks,
                    })),
                  })
                  await requestPayment(payment)
                  mutateCloud('list-order')
                  sMutate()
                  switchTab({ url: `/pages/cast-list/index` })
                } catch ({ errMsg }) {
                  if (/requestPayment:fail cancel/.test(errMsg)) {
                    showToast({ title: '支付取消', icon: 'none' })
                  } else {
                    showToast({ title: '网络错误', icon: 'none' })
                  }
                }
              }
            }}
          >
            {step === 3 ? '确认支付' : '下一步'}
          </Button>
        </Row>
      </View>
      {step === 0 &&
        pAuditedData &&
        (pAuditedData.length ? (
          <RecycleView
            className={styles.mainArea}
            refresherEnabled
            refresherTriggered={pLoading}
            onRefresherRefresh={async () => {
              setPLoading(true)
              await pMutate()
              setPLoading(false)
            }}
            data={pAuditedData.map((v: WBG.Promotion) => ({
              ...v,
              height: 260,
            }))}
            renderItem={(item, index) => {
              return (
                <PromotionItem
                  {...((item as unknown) as WBG.Promotion)}
                  checked={item._id === promotionId}
                  check={(c, v) => {
                    c && setPromotionId(v)
                  }}
                />
              )
            }}
          />
        ) : (
          <View className="empty-view small-text">您没有审核通过的广告</View>
        ))}
      {step === 1 &&
        sData &&
        (sData.length ? (
          <RecycleView
            className={styles.mainArea}
            refresherEnabled
            refresherTriggered={sLoading}
            onRefresherRefresh={async () => {
              setSLoading(true)
              await sMutate()
              setSLoading(false)
            }}
            data={sData.map((v: WBG.Screen) => ({
              ...v,
              height: 260,
            }))}
            renderItem={(item, index) => {
              return (
                <ScreenItem
                  {...((item as unknown) as WBG.Screen)}
                  checked={screenIds.includes(item._id)}
                  check={(c, v) => {
                    if (c) {
                      setScreenIds(screenIds.concat([v]))
                    } else {
                      const i = screenIds.indexOf(v)
                      setScreenIds(
                        screenIds.slice(0, i).concat(screenIds.slice(i + 1))
                      )
                    }
                  }}
                />
              )
            }}
          />
        ) : (
          <View className="empty-view small-text">
            您附近没有找到可用的大屏
          </View>
        ))}
      {step === 2 && (
        <View className={styles.mainArea}>
          <View className={styles.basicArea}>
            <Row justify="space-around">
              <View>
                <View>
                  <Text className="large-text">{totalWeekCount}</Text>
                  <Text className="small-text">个</Text>
                </View>
                <Text className="small-text">广告位总数</Text>
              </View>
              <View>
                <View>
                  <Text className="large-text">{soldoutWeekCount}</Text>
                  <Text className="small-text">个</Text>
                </View>
                <Text className="small-text">已告罄</Text>
              </View>
              <View>
                <View>
                  <Text className="large-text">{almostSoldoutWeekCount}</Text>
                  <Text className="small-text">个</Text>
                </View>
                <Text className="small-text">接近告罄</Text>
              </View>
            </Row>
            <Text className="small-text">(一个大屏上投放一周为一个广告位)</Text>
          </View>
          <View className={styles.middleArea}>
            <Space className={styles.middleBox} direction="vertical" size={12}>
              <Text className="medium-text">未来广告位</Text>
              {weekOptions.map((v, i) => {
                const count = casts.reduce((pre, cur) => {
                  return pre + (cur.weeks.includes(v.week) ? 1 : 0)
                }, 0)
                return (
                  <Row key={i} justify="space-between" align="middle">
                    <Checkbox
                      checked={weeks.includes(v.week)}
                      value={v.week}
                      onChange={(c, e, v) => {
                        if (weeks.slice(0, 4).includes(v as string)) {
                          return
                        }
                        if (c) {
                          setWeeks(weeks.concat([v as string]).sort())
                        } else {
                          const i = weeks.indexOf(v as string)
                          setWeeks(weeks.slice(0, i).concat(weeks.slice(i + 1)))
                        }
                      }}
                    >
                      {dayjs(v.week).format('M月D日')} -{' '}
                      {dayjs(v.week).add(6, 'day').format('M月D日')}
                    </Checkbox>
                    {weeks.includes(v.week) ? (
                      count === 0 ? (
                        <Tag color="red">已告罄</Tag>
                      ) : count < screenIds.length ? (
                        <Tag color="yellow">{count} 个大屏</Tag>
                      ) : (
                        <Tag color="green">{count} 个大屏</Tag>
                      )
                    ) : (
                      <View />
                    )}
                  </Row>
                )
              })}
            </Space>
          </View>
        </View>
      )}
      {step === 3 && (
        <View className={styles.mainArea}>
          <View className={styles.middleArea}>
            <Space className={styles.middleBox} direction="vertical" size={12}>
              <Text className="medium-text">投放广告</Text>
              <PromotionItem
                {...pAuditedData?.find(
                  (v: WBG.Promotion) => v._id === promotionId
                )}
              />
            </Space>
          </View>
          <View className={styles.middleArea}>
            <Space className={styles.middleBox} direction="vertical" size={12}>
              <Text className="medium-text">投放屏幕</Text>
              {casts.map((v, i) => (
                <Row key={i} justify="space-between" align="middle">
                  <View key={i} className="ellipsis">
                    {sMap.get(v.screenId)?.name}
                  </View>
                  <Tag color="green">{v.weeks.length} 个广告位</Tag>
                </Row>
              ))}
            </Space>
          </View>
          <View className={styles.middleArea}>
            <Row justify="space-between" align="middle">
              <Text className="medium-text">总价</Text>
              <Space align="center" size={12}>
                <Text className={styles.alarmText}>￥{cost}</Text>
                {originalCost > cost && (
                  <Text className={styles.deletedText}>￥{originalCost}</Text>
                )}
              </Space>
            </Row>
          </View>
          <View className={styles.middleArea}>
            <Row align="middle">
              <Checkbox
                checked={agreement}
                onChange={c => {
                  setAgreement(c)
                }}
              >
                我同意
              </Checkbox>
              <Navigator
                url="/pages/agreement/index"
                className={styles.agreementNav}
              >
                《蜗大郎客户服务协议》
              </Navigator>
            </Row>
          </View>
        </View>
      )}
    </Login>
  )
}
